package com.buddha.api.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.buddha.api.entity.Menu;
import com.buddha.api.entity.Role;
import com.buddha.api.entity.User;
import com.buddha.api.mapper.UserMapper;
import com.buddha.api.service.IMenuService;
import com.buddha.api.service.IRoleService;
import com.buddha.api.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.buddha.api.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author mybatis-plus
 * @since 2023-07-06
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    IRoleService iRoleService;

    @Autowired
    UserMapper userMapper;

    @Autowired
    RoleServiceImpl roleService;

    @Autowired
    IMenuService menuService;

    @Autowired
    UserRoleServiceImpl userRoleService;

    @Autowired
    RedisUtil redisUtil;

    @Override
    public User findByUsername(String username) {
        return getOne(new QueryWrapper<User>().eq("username",username));
    }

    @Override
    public String getUserAuthorityInfo(long userId) {
        User user = userMapper.selectById(userId);
        String authority = "";

        if (redisUtil.hasKey("GrantedAuthority"+user.getUsername())){
            authority = (String) redisUtil.get("GrantedAuthority" + user.getUsername());
            return authority;
        }

        List<Role> roles = iRoleService.list(new QueryWrapper<Role>().inSql("id", "select r_id from user_role where r_id=" + userId));
        if (roles.size() > 0){
            String rCodes = roles.stream().map(r -> "ROLE_"+r.getCode()).collect(Collectors.joining(","));
            authority = rCodes.concat(",");
        }
        List<Long> menuIds = userMapper.selectMenuIds(userId);
        if (menuIds.size() > 0){
            List<Menu> menus = menuService.listByIds(menuIds);
            String permissions = menus.stream().map(r -> r.getPerms()).collect(Collectors.joining(","));

            authority = authority.concat(permissions);
        }
        redisUtil.set("GrantedAuthority"+user.getUsername(),authority,60*60);
        return authority;
    }

    @Override
    public void clearUserAuthority(String username) {
        redisUtil.del("GrantedAuthority" + username);
    }

    @Override
    public void clearUserAuthorityByRole(long roleId) {
        for (User user : list(new QueryWrapper<User>().inSql("id", "select u_id from user_role where r_id=" + roleId))) {
            clearUserAuthority(user.getUsername());
        }

    }

    @Override
    public void clearUserAuthorityByMenu(long menuId) {
        List<String> usernames = userMapper.userNameByMenuId(menuId);
        usernames.forEach(r -> clearUserAuthority(r));
    }
}
